package com.yike.order.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lkl.laop.sdk.LKLSDK;
import com.lkl.laop.sdk.exception.SDKException;
import com.lkl.laop.sdk.request.V3LabsTransMicropayRequest;
import com.yike.common.Response.*;
import com.yike.common.base.BaseServiceImpl;
import com.yike.common.constant.CommonConstant;
import com.yike.common.constant.RocketMqConstant;
import com.yike.common.entity.CommissionGoodsMq;
import com.yike.common.entity.CommissionOrderMq;
import com.yike.common.entity.OrderLklSeparate;
import com.yike.common.entity.SysInfo;
import com.yike.common.exception.BusinessException;
import com.yike.common.pagination.Paging;
import com.yike.common.pagination.PageInfo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yike.common.redis.RedisUtil;
import com.yike.common.request.SacsSeparateNotReq;
import com.yike.common.tool.LoginUtil;
import com.yike.common.tool.StringUtil;
import com.yike.order.api.vo.ShopDataStatisticsFeignVo;
import com.yike.order.entity.Order;
import com.yike.order.entity.OrderDetail;
import com.yike.order.entity.Refund;
import com.yike.order.entity.RefundDetail;
import com.yike.order.lkl.api.V3ApiLabs;
import com.yike.order.lkl.api.V3SacsSeparateApi;
import com.yike.order.mapper.*;
import com.yike.order.param.*;
import com.yike.order.service.OrderDetailService;
import com.yike.order.service.OrderService;
import com.yike.order.service.WxPayService;
import com.yike.order.vo.*;
import com.yike.product.api.service.GoodsFeignService;
import com.yike.product.api.vo.GoodsFeignVo;
import com.yike.user.api.service.ShopFeignService;
import com.yike.user.api.vo.ShopFeignVo;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.client.producer.SendResult;
import org.springframework.beans.BeanUtils;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单表 服务实现类
 *
 * @author yike
 * @since 2024-07-18
 */
@Slf4j
@Service
public class OrderServiceImpl extends BaseServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private RefundMapper refundMapper;
    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private WxPayService wxPayService;
    @Resource
    private GoodsFeignService goodsFeignService;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private RefundDetailMapper refundDetailMapper;
    @Resource
    private ShopFeignService shopFeignService;

    @Resource
    private V3ApiLabs v3ApiLabs;

    @Resource
    private OrderLklSeparateMapper orderLklSeparateMapper;

    @Resource
    private V3SacsSeparateApi v3SacsSeparateApi;

    @Resource
    private SysInfoMapper sysInfoMapper;


    @Override
    public Map<String, Object> lklCallback(LklPayCallback lklPayCallback) {

        Map<String, Object> result = new HashMap<>();
        try {

            Order order = orderMapper.selectOne( new LambdaQueryWrapper<Order>().eq(Order::getTradeNo, lklPayCallback.getTradeNo()));
            if (order == null) {
                result.put("code", "ERROR");
                result.put("msg", "订单不存在");
                return result;
            }

            if(lklPayCallback.getAccountType().equals("ALIPAY")){
                order.setPayway(2);
            }else if(lklPayCallback.getAccountType().equals("WECHAT")){
                order.setPayway(1);
            }else if(lklPayCallback.getAccountType().equals("UQRCODEPAY")){
                order.setPayway(3);
            }else if(lklPayCallback.getAccountType().equals("BESTPAY")){
                order.setPayway(4);
            }else if(lklPayCallback.getAccountType().equals("SUNING")){
                order.setPayway(5);
            }

            if (lklPayCallback.getTradeStatus().equals("SUCCESS")){
                order.setStatus(1);
                //支付时间
                order.setPayTime(new Date());
                if(lklPayCallback.getAccountType().equals("ALIPAY")){
                    order.setPayway(2);
                }else if(lklPayCallback.getAccountType().equals("WECHAT")){
                    order.setPayway(1);
                }
                order.setTradeNo(lklPayCallback.getTradeNo());
                order.setLogNo(lklPayCallback.getLogNo());
                orderMapper.updateById(order);
                // 此处用来处理代理商当天分润
                this.orderMq(order);
                order.setLogNo(lklPayCallback.getLogNo());
                //分账申请
                this.sacsSeparatePost(order);
            }

            //未支付
            if (lklPayCallback.getTradeStatus().equals("FAIL") || lklPayCallback.getTradeStatus().equals("REFUND")
                    || lklPayCallback.getTradeStatus().equals("CLOSED")){
                order.setStatus(2);
                orderMapper.updateById(order);
            }

            //已退款
            if ( lklPayCallback.getTradeStatus().equals("REFUND")){
                order.setStatus(3);
                orderMapper.updateById(order);
            }

            result.put("code", "SUCCESS");
            result.put("message", "执行成功");

            return result;
        } catch (Exception e) {
            result.put("code", "ERROR");
            result.put("message", e.getMessage());
            return result;
        }
    }



    @Override
    public Map<String, Object> sacsSeparateNot(SacsSeparateNotReq req) {

        Map<String, Object> result = new HashMap<>();
        try {
            Order order = orderMapper.selectOne( new LambdaQueryWrapper<Order>().eq(Order::getLogNo, req.getLogNo()));
            if (order == null) {
                result.put("code", "ERROR");
                result.put("msg", "订单不存在");
                return result;
            }

            OrderLklSeparate orderLklSeparate = orderLklSeparateMapper.selectOne( new LambdaQueryWrapper<OrderLklSeparate>()
                    .eq(OrderLklSeparate::getSeparateNo, req.getSeparateNo()).eq(OrderLklSeparate::getOutSeparateNo, req.getOutSeparateNo()));

            //分账回调
            if(req.getCmdType().equals("SEPARATE")){

            }

            orderLklSeparate.setStatus(req.getStatus());
            orderLklSeparate.setFinalStatus(req.getFinalStatus());
            orderLklSeparate.setUpdateTime(new Date());
            orderLklSeparateMapper.updateById(orderLklSeparate);

            result.put("code", "SUCCESS");
            result.put("message", "执行成功");

            return result;
        } catch (Exception e) {
            result.put("code", "ERROR");
            result.put("message", e.getMessage());
            return result;
        }
    }

    @Override
    public Integer getLklStatus(String orderNo) {
//        Map<String, Object> result = new HashMap<>();
        Integer status = 0;
        try {
            Order order = orderMapper.selectOne( new LambdaQueryWrapper<Order>().eq(Order::getOrderNo, orderNo));
            if (order == null) {
                //result.put("code", 500);
                //result.put("msg", "订单不存在");
                return status;
            }
            //result.put("orderNo", orderNo);


            //根据订单获取店铺信息
            Map<String ,Object> shopInfo = shopFeignService.getShopDetails(order.getShopId());
            if(ObjectUtil.isNull(shopInfo) || !shopInfo.containsKey("id")){
                throw new BusinessException(500, "店铺信息异常");
            }
            Map<String ,Object> shopDetails = (Map<String ,Object>)shopInfo.get("shopDetails");
            if(ObjectUtil.isNull(shopDetails) || !shopDetails.containsKey("id")){
                throw new BusinessException(500, "店铺信息异常");
            }
            String merchantNo = shopDetails.get("externalCustomerNo").toString();
            String termNo = shopDetails.get("termNo").toString();

            //查询订单信息
            LklPayQueryResponse lklPayQueryResponse = v3ApiLabs.tradeQuery(merchantNo, termNo, orderNo, order.getTradeNo());
            order.setLogNo(lklPayQueryResponse.getLogNo());

            if(lklPayQueryResponse.getAccountType().equals("ALIPAY")){
                order.setPayway(2);
            }else if(lklPayQueryResponse.getAccountType().equals("WECHAT")){
                order.setPayway(1);
            }else if(lklPayQueryResponse.getAccountType().equals("UQRCODEPAY")){
                order.setPayway(3);
            }else if(lklPayQueryResponse.getAccountType().equals("BESTPAY")){
                order.setPayway(4);
            }else if(lklPayQueryResponse.getAccountType().equals("SUNING")){
                order.setPayway(5);
            }

            if (lklPayQueryResponse.getTradeState().equals("SUCCESS")){
                //result.put("status", 1);
                order.setStatus(1);
                order.setPayTime(new Date());
                status = 1;
                //分账申请
               // this.sacsSeparatePost(order);

            }
            else if (lklPayQueryResponse.getTradeState().equals("FAIL")){
                //result.put("status", 2);
                order.setStatus(2);
                status = 2;

            }
            else if (lklPayQueryResponse.getTradeState().equals("CREATE") || lklPayQueryResponse.getTradeState().equals("DEAL")
                    || lklPayQueryResponse.getTradeState().equals("INIT")){
               // result.put("status", 0);
                order.setStatus(0);
                status = 0;

            }
            else if (lklPayQueryResponse.getTradeState().equals("REFUND")){
                //result.put("status", 3);
                order.setStatus(3);
                status = 3;

            }
            else if (lklPayQueryResponse.getTradeState().equals("PART_REFUND")){
               // result.put("status", 4);
                order.setStatus(4);
                status = 4;

            }
            if(lklPayQueryResponse.getAccountType().equals("WECHAT")){
                order.setPayway(3);
            }
            if(lklPayQueryResponse.getAccountType().equals("ALIPAY")){
                order.setPayway(4);
            }


            orderMapper.updateById(order);

            return status;
        } catch (Exception e) {
            //result.put("code", 500);
            //result.put("msg", e.getMessage());
            //return result;
            throw new RuntimeException(e.getMessage());
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String saveOrder(AddOrderParam addOrderParam) throws Exception {
        // 通过redis防止重复提交
        if (redisUtil.hasKey(CommonConstant.ORDER_ADD_CHECK + LoginUtil.getUserId())) {
            throw new BusinessException(500, "请勿重复提交订单");
        }
        redisUtil.set(CommonConstant.ORDER_ADD_CHECK + LoginUtil.getUserId(), 1, 3);

        // 从商品服务获取商品信息
        Set<Long> goodsIds = addOrderParam.getOrderDetails().stream().map(AddOrderDetailParam::getGoodsId).collect(Collectors.toSet());
        List<GoodsFeignVo> goodsFeignVos = goodsFeignService.list(goodsIds);
        if (goodsFeignVos == null || goodsFeignVos.isEmpty()) {
            throw new BusinessException(500, "商品信息异常");
        }
        Map<Long, GoodsFeignVo> goodsFeignVoMap = goodsFeignVos.stream().collect(Collectors.toMap(GoodsFeignVo::getId, a -> a));
        // 验证商品信息和订单价格是否一致
        BigDecimal totalAmount = new BigDecimal(0);
        for (AddOrderDetailParam addOrderDetailParam : addOrderParam.getOrderDetails()) {
            GoodsFeignVo goodsFeignVo = goodsFeignVoMap.get(addOrderDetailParam.getGoodsId());
            // 判断商品是否存在
            if (goodsFeignVo == null) {
                throw new BusinessException(addOrderDetailParam.getGoodsName() + " 信息异常，请联系工作人员");
            }
            // 判断商品是否是当前店铺的
            if (!addOrderParam.getShopId().equals(goodsFeignVo.getShopId())) {
                throw new BusinessException(addOrderDetailParam.getGoodsName() + " 信息异常，请联系工作人员");
            }
            // 判断商品价格是否有调整
            if (addOrderDetailParam.getPrice().compareTo(goodsFeignVo.getSellPrice()) != 0) {
                throw new BusinessException(addOrderDetailParam.getGoodsName() + " 价格发生变化，请重新下单");
            }
            totalAmount = totalAmount.add(goodsFeignVo.getSellPrice().multiply(BigDecimal.valueOf(addOrderDetailParam.getNumber())));

            // 因为是线下实体店目前不做库存验证

        }

        //校验订单价格是否一致
        if (totalAmount.compareTo(addOrderParam.getAmount()) != 0) {
            throw new BusinessException(500, "订单金额异常");
        }

        //数据保存
        Order order = new Order();
        order.setOrderNo(StringUtil.randomDateNum());
        order.setAmount(totalAmount);
        order.setActualAmount(order.getAmount());
        order.setShopId(addOrderParam.getShopId());
        order.setMacNo(addOrderParam.getMacNo());

        // 需要判断当前店铺是否开启了值守
        // 客户端扫码的时候需要判断当前店铺是否开启了一键调价
        ShopFeignVo shopFeignVo = shopFeignService.getShop(addOrderParam.getShopId());
        if (shopFeignVo == null) {
            throw new BusinessException("店铺信息异常，请联系工作人员");
        }
        if (shopFeignVo.getCloudGarrisonFlag()) {
            order.setCloudGarrisonFlag(true);
            order.setCloudGarrisonCode(shopFeignVo.getCloudGarrisonCode());
        }
        super.save(order);

        // 保存订单详情
        List<OrderDetail> orderDetails = goodsFeignVos.stream().map(goodsFeignVo -> {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(goodsFeignVo, orderDetail);
            orderDetail.setGoodsId(goodsFeignVo.getId());
            orderDetail.setOrderId(order.getId());
            orderDetail.setGoodsName(goodsFeignVo.getName());

            // 从 addOrderParam 中匹配商品 ID 来设置数量
            addOrderParam.getOrderDetails().stream()
                    .filter(orderDetailParam -> orderDetailParam.getGoodsId().equals(goodsFeignVo.getId()))
                    .findFirst()
                    .ifPresent(orderDetailParam -> orderDetail.setNumber(orderDetailParam.getNumber()));

            return orderDetail;
        }).collect(Collectors.toList());

        orderDetailService.saveBatch(orderDetails);

        // 推送消息到mq，如果5分钟未支付则关闭当前订单
        SendResult sendResult = rocketMQTemplate.syncSend("close-order-topic", MessageBuilder.withPayload(order.getId()).build(), 3000, 9);
        log.info("destroy-room-topic 推送到延迟队列结果：" + sendResult);

        return order.getOrderNo();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateOrder(Order order) throws Exception {
        return super.updateById(order);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteOrder(Long id) throws Exception {
        return super.removeById(id);
    }

    @Override
    public Paging<OrderListVo> getUserOrderList(OrderPageParam orderPageParam) throws Exception {
        Page<Order> page = new PageInfo<>(orderPageParam);
        IPage<OrderListVo> iPage = orderMapper.getUserOrderList(page, LoginUtil.getUserId(), orderPageParam);
        return new Paging<OrderListVo>(iPage);
    }

    @Override
    public Paging<OrderListVo> getShopOrderList(ShopOrderPageParam shopOrderPageParam) throws Exception {
        Page<Order> page = new PageInfo<>(shopOrderPageParam);
        if (shopOrderPageParam.getShopId() == null) {
            shopOrderPageParam.setShopId(LoginUtil.getShopId());
        }
        IPage<OrderListVo> iPage = orderMapper.getShopOrderList(page, shopOrderPageParam);
        return new Paging<OrderListVo>(iPage);
    }

    @Override
    public Paging<RefundVo> getShopRefundList(ShopRefundPageParam shopRefundPageParam) throws Exception {
        Page<Refund> page = new PageInfo<>(shopRefundPageParam);
        if (shopRefundPageParam.getShopId() == null) {
            shopRefundPageParam.setShopId(LoginUtil.getShopId());
        }
        IPage<RefundVo> iPage = refundMapper.getShopRefundList(page, shopRefundPageParam);
        return new Paging<RefundVo>(iPage);
    }

    @Override
    public Integer pay(PayOrderParam payOrderParam) throws ParseException, SDKException {
        // 获取订单信息
        Order order = orderMapper.selectOne(Wrappers.lambdaQuery(Order.class).eq(Order::getOrderNo, payOrderParam.getOrderNo()));
        if (ObjectUtil.isNull(order)) {
            throw new BusinessException(500, "订单不存在");
        }

        // 如果订单状态不是待支付，直接返回
        if (order.getStatus() != 0) {
            throw new BusinessException(500, "订单状态异常");
        }


        WxPayRequestParam wxPayRequestParam = new WxPayRequestParam();
        wxPayRequestParam.setAuthCode(payOrderParam.getAuthCode());
        wxPayRequestParam.setBody(payOrderParam.getOrderNo());
        wxPayRequestParam.setOutTradeNo(order.getOrderNo());

        //微信支付单位是分
        BigDecimal amount = order.getAmount();
        amount = amount.multiply(BigDecimal.valueOf(100));
        wxPayRequestParam.setTotalFee(amount.stripTrailingZeros().toPlainString());
        Map<String, String> result = wxPayService.microPay(wxPayRequestParam);
        log.info("微信支付结果：{}", JSONObject.toJSONString(result));

//        if ("SUCCESS".equals(result.get("return_code"))
//                && "SUCCESS".equals(result.get("result_code"))
//                && "MICROPAY".equals(result.get("trade_type"))) {
        if (true) {
            //支付状态-已支付
            order.setStatus(1);
            //支付时间
            DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
            //Date payTime = df.parse(result.get("time_end"));
            order.setPayTime(new Date());
            //微信订单号
            order.setWxTransactionId(result.get("transaction_id"));
            //微信支付
            order.setPayway(1);
            orderMapper.updateById(order);

            // 此处用来处理代理商当天分润
            this.orderMq(order);
        } else {
            // order.setStatus(5); // 此处不需要将订单修改为异常状态，防止用户支付失败重新付款无法操作
            // order.setErrorDesc(result.get("return_msg"));
            // orderMapper.updateById(order);
            throw new BusinessException(500, result.get("return_msg"));
        }

        return order.getStatus();
    }


    public void orderMq(Order order) throws ParseException, SDKException {
        // 此处用来处理代理商当天分润，不一定准确，最终分润以定时任务统计为准
        CommissionOrderMq agentCommissionMq = new CommissionOrderMq();
        agentCommissionMq.setType(1);
        agentCommissionMq.setPayway(order.getPayway());
        agentCommissionMq.setShopId(order.getShopId());
        agentCommissionMq.setAmount(order.getAmount());
        agentCommissionMq.setOrderId(order.getId());
        agentCommissionMq.setPayTime(order.getPayTime());
        // 获取订单详情
        List<OrderDetailVo> orderDetailVos = orderDetailMapper.getOrderDetailVoByOrderId(order.getId());
        List<CommissionGoodsMq> goodsMqs = orderDetailVos.stream()
                .map(orderDetailVo -> {
                    CommissionGoodsMq goodsMq = new CommissionGoodsMq();
                    BeanUtils.copyProperties(orderDetailVo, goodsMq);
                    return goodsMq;
                })
                .collect(Collectors.toList());
        agentCommissionMq.setGoodsMqs(goodsMqs);

        SendResult sendResult = rocketMQTemplate.syncSend(RocketMqConstant.AGENT_COMMISSION_TOPIC, JSON.toJSONString(agentCommissionMq), 3000);
        log.info(RocketMqConstant.AGENT_COMMISSION_TOPIC + " 推送到队列结果：" + sendResult);
    }



    @Override
    public Integer lklPay(PayOrderParam payOrderParam) throws ParseException, SDKException {
//        Map<String, Object> map = new HashMap<>();
        Integer Status = 0;
        // 获取订单信息
        Order order = orderMapper.selectOne(Wrappers.lambdaQuery(Order.class).eq(Order::getOrderNo, payOrderParam.getOrderNo()));
        if (ObjectUtil.isNull(order)) {
            throw new BusinessException(500, "订单不存在");
        }

        // 如果订单状态不是待支付，直接返回
        if (order.getStatus() != 0) {
            throw new BusinessException(500, "订单状态异常");
        }

        //拉卡拉支付
        LklPayResponse lklPayResponse = this.lklPaySendPost(order,payOrderParam);
        if (ObjectUtil.isNull(lklPayResponse)) {
            throw new BusinessException(500, "拉卡拉支付失败");
        }
//        map.put("needQuery", lklPayResponse.getNeedQuery());

        if (ObjectUtil.isNull(lklPayResponse.getNeedQuery()) || lklPayResponse.getNeedQuery().equals("1")) {
//            map.put("msg", "支付中");
//            map.put("status",0);
            Status = 0;
            return Status;
        } else {
            //支付状态-已支付
            order.setStatus(1);
            //支付时间
            DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
            //Date payTime = df.parse(result.get("time_end"));
            order.setPayTime(new Date());
            //交易流水号
            order.setTradeNo(lklPayResponse.getTradeNo());
            order.setLogNo(lklPayResponse.getLogNo());

            //拉卡拉支付
            order.setPayway(3);
            orderMapper.updateById(order);

//            map.put("status",1);
            // 此处用来处理代理商当天分润
            this.orderMq(order);
            Status = 1;
            return Status;
        }

    }


    /**
     * 拉卡拉分账请求
     * @param order
     */
    public void sacsSeparatePost(Order order) throws SDKException, IOException {
        try {

            //查询订单是否已分账
            OrderLklSeparate orderLklSeparateInfo = orderLklSeparateMapper.selectOne(new LambdaQueryWrapper<OrderLklSeparate>().eq(OrderLklSeparate::getOrderNo, order.getOrderNo()).last("limit 1"));

            if(ObjectUtil.isNotEmpty(orderLklSeparateInfo)){
                return;
            }
            //根据订单获取店铺信息
            Map<String ,Object> shopInfo = shopFeignService.getShopDetails(order.getShopId());
            if(ObjectUtil.isNull(shopInfo) || !shopInfo.containsKey("id")){
                throw new BusinessException(500, "店铺信息异常");
            }

            Map<String ,Object> shopDetails = (Map<String ,Object>)shopInfo.get("shopDetails");
            if(ObjectUtil.isNull(shopDetails) || !shopDetails.containsKey("id")){
                throw new BusinessException(500, "店铺信息异常");
            }

            SysInfo  sysInfo = sysInfoMapper.selectOne(new LambdaQueryWrapper<SysInfo>().last("limit 1"));

            //分账金额
            BigDecimal actualAmount = order.getAmount().multiply(new BigDecimal(100));
            BigDecimal commissionRate =  BigDecimal.valueOf((Double) shopInfo.get("commissionRate"));
            BigDecimal commission = actualAmount.multiply(commissionRate).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);

            OrderLklSeparate orderLklSeparate = new OrderLklSeparate();
            orderLklSeparate.setOrderNo(order.getOrderNo()); //订单号
            orderLklSeparate.setMerchantNo(shopDetails.get("externalCustomerNo").toString()); //商户号
            orderLklSeparate.setShopId(order.getShopId()); // 店铺ID
            orderLklSeparate.setCreateBy(order.getCreateBy());
            orderLklSeparate.setUpdateBy(order.getUpdateBy());
            orderLklSeparate.setLogNo(order.getLogNo()); // 订单对账流水号
            orderLklSeparate.setOutSeparateNo(StringUtil.getStrNo()); // 分账流水号
            orderLklSeparate.setTotalAmt(commission.intValue());  // 分账总金额 （分）
            orderLklSeparate.setCalType(1); // 0- 按照指定金额，1- 按照指定比例
            orderLklSeparate.setStatus("PROCESSING");
            orderLklSeparate.setLogDate(order.getPayTime());

            LklSacsSeparateResponse lklSacsSeparateResponse = v3SacsSeparateApi.sacsSeparate(orderLklSeparate,sysInfo.getReceiverNo());

            orderLklSeparate.setSeparateNo(lklSacsSeparateResponse.getSeparateNo());

            orderLklSeparateMapper.insert(orderLklSeparate);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }



    }



    public LklPayResponse lklPaySendPost(Order order,PayOrderParam payOrderParam) throws ParseException, SDKException {
        //根据订单获取店铺信息
        Map<String ,Object> shopInfo = shopFeignService.getShopDetails(order.getShopId());
        if(ObjectUtil.isNull(shopInfo) || !shopInfo.containsKey("id")){
            throw new BusinessException(500, "店铺信息异常");
        }

        Map<String ,Object> shopDetails = (Map<String ,Object>)shopInfo.get("shopDetails");
        if(ObjectUtil.isNull(shopDetails) || !shopDetails.containsKey("id")){
            throw new BusinessException(500, "店铺信息异常");
        }
        shopDetails.put("longitude",shopInfo.get("longitude"));
        shopDetails.put("latitude",shopInfo.get("latitude"));


        LklPayResponse lklPayResponse = v3ApiLabs.LabsTransMicroPay(order, shopDetails,payOrderParam.getAuthCode());

        return lklPayResponse;
    }

    @Override
    @Transactional
    public boolean refund(RefundOrderParam refundOrderParam) throws ParseException, SDKException, IOException {
        // 通过redis防止重复提交
        if (redisUtil.hasKey(CommonConstant.ORDER_REFUND_CHECK + refundOrderParam.getOrderNo())) {
            throw new BusinessException(500, "退款频率过快，请稍后再操作");
        }
        redisUtil.set(CommonConstant.ORDER_REFUND_CHECK + refundOrderParam.getOrderNo(), 1, 3);

        Order order = orderMapper.selectOne(Wrappers.lambdaQuery(Order.class)
                .eq(Order::getOrderNo, refundOrderParam.getOrderNo()));

        if (ObjectUtil.isNull(order)) {
            throw new BusinessException(500, "订单信息异常");
        }

        // 只有支付成功和部分退款的订单可以进行退款操作
        if (order.getStatus() != 1 && order.getStatus() != 4 && order.getStatus() != 3) {
            throw new BusinessException(500, "订单信息异常");
        }

        // 校验退款金额是否正常
        // 获取当前订单已退款金额
        BigDecimal beforeRefundFee = refundMapper.getRefundAmountByOrderId(order.getId());
        // 退款金额加已退款金额不得大于订单支付金额
        if (order.getAmount().compareTo(beforeRefundFee.add(refundOrderParam.getRefundFee())) < 0) {
            throw new BusinessException(500, "退款金额不能大于订单金额");
        }

        // 限制退款时间最大为7天，防止订单已经分润结算
        // 获取当前时间
        Date now = new Date();
        // 获取订单的支付时间
        Date payTime = order.getPayTime();
        // 创建 Calendar 实例，用于计算7天后的时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(payTime);
        calendar.add(Calendar.DAY_OF_YEAR, 7);
        // 检查支付时间是否超过7天
        if (calendar.getTime().before(now)) {
            throw new BusinessException(500, "超过7天的订单无法退款");
        }
        SysInfo sysInfo = sysInfoMapper.selectOne(Wrappers.lambdaQuery(SysInfo.class).eq(SysInfo::getId, 1));
        //查询订单是否已分账
        OrderLklSeparate  orderLklSeparate = orderLklSeparateMapper.selectOne(Wrappers.lambdaQuery(OrderLklSeparate.class)
                .eq(OrderLklSeparate::getOrderNo,order.getOrderNo()).last("limit 1"));

        if(ObjectUtil.isNotEmpty(orderLklSeparate) && StringUtil.isBlank(orderLklSeparate.getFallbackSeparateNo())){
            orderLklSeparate.setFallbackOutSeparateNo(StringUtil.randomDateNumOr8());
            LklSacsFallbackResponse lklSacsFallbackResponse = v3SacsSeparateApi.sacsFallback(orderLklSeparate,sysInfo.getReceiverNo());
            orderLklSeparate.setFallbackSeparateNo(lklSacsFallbackResponse.getSeparateNo());
            if("SUCCESS".equals(lklSacsFallbackResponse.getStatus())){
                orderLklSeparate.setStatus("FALLBACK_END");
            }
            orderLklSeparateMapper.updateById(orderLklSeparate);
        }



        Map<String ,Object> shopInfo = shopFeignService.getShopDetails(order.getShopId());
        if(ObjectUtil.isNull(shopInfo) || !shopInfo.containsKey("id")){
            throw new BusinessException(500, "店铺信息异常");
        }

        Map<String ,Object> shopDetails = (Map<String ,Object>)shopInfo.get("shopDetails");
        if(ObjectUtil.isNull(shopDetails) || !shopDetails.containsKey("id")){
            throw new BusinessException(500, "店铺信息异常");
        }
        String refundNo = "T" + StringUtil.getStrNo();
        //拉卡拉退款
        LklRefundResponse lklRefundResponse = v3ApiLabs.refund(shopDetails.get("externalCustomerNo").toString(), shopDetails.get("termNo").toString(),
                order.getOrderNo(),refundNo,order.getTradeNo(),
                String.valueOf(refundOrderParam.getRefundFee().multiply(new BigDecimal("100")).longValue()));

        // 保存退款订单信息
        Refund refund = new Refund();
        refund.setShopId(order.getShopId());
        refund.setOrderId(order.getId());
        refund.setAmount(refundOrderParam.getRefundFee());
        refund.setRefundNo(refundNo);
        refund.setRefundDesc(refundOrderParam.getRefundDesc());
        refund.setStatus(0);
        refund.setCreateBy(LoginUtil.getUserId());
        refundMapper.insert(refund);

        // 保存退款商品信息
        for (RefundGoodsParam refundGoodsParam : refundOrderParam.getGoodsList()) {
            // 获取订单商品信息
            OrderDetail orderDetail = orderDetailMapper.selectOne(Wrappers.lambdaQuery(OrderDetail.class)
                    .eq(OrderDetail::getOrderId, order.getId())
                    .eq(OrderDetail::getGoodsId, refundGoodsParam.getGoodsId()));
            if (ObjectUtil.isNull(orderDetail) || orderDetail.getNumber() < refundGoodsParam.getNumber()) {
                throw new BusinessException(500, "商品信息异常");
            }

            // 保存退款订单详情
            RefundDetail refundDetail = new RefundDetail();
            BeanUtils.copyProperties(orderDetail, refundDetail);
            refundDetail.setRefundId(refund.getId());
            refundDetail.setNumber(refundGoodsParam.getNumber());
            refundDetailMapper.insert(refundDetail);
        }

//        //生成微信单号
//        WxRefundRequestParam wxRefundRequestParam = new WxRefundRequestParam();
//        //退款单号
//        wxRefundRequestParam.setOutRefundNo(refund.getRefundNo());
//        //商户单号
//        wxRefundRequestParam.setOutTradeNo(order.getOrderNo());
//        //订单总金额
//        wxRefundRequestParam.setTotalFee(order.getAmount().multiply(new BigDecimal(100)).intValue());
//        //退款金额
//        wxRefundRequestParam.setRefundFee(refundOrderParam.getRefundFee().multiply(new BigDecimal(100)).intValue());
//        //退款原因
//        wxRefundRequestParam.setRefundDesc(refundOrderParam.getRefundDesc());
//
//        Map<String, String> result = wxPayService.refund(wxRefundRequestParam);
//        log.info("微信退款结果：{}", JSONObject.toJSONString(result));


//        if ("SUCCESS".equals(result.get("return_code"))
//                && "SUCCESS".equals(result.get("result_code"))) {


        if (ObjectUtil.isNotEmpty(lklRefundResponse)) {
//            // 判断是否是全额退款
//            if (order.getAmount().compareTo(beforeRefundFee.add(refundOrderParam.getRefundFee())) == 0) {
//                order.setStatus(3);
//            } else {
//                order.setStatus(4);
//            }
            // 业务要求全部显示为已退款
            order.setStatus(3);
            orderMapper.updateById(order);
            order.setRefundAmount(beforeRefundFee.add(refundOrderParam.getRefundFee()));
            order.setActualAmount(order.getAmount().subtract(order.getRefundAmount()));
            orderMapper.updateById(order);

            // 如果是退商品还需要扣减订单详情里面的商品数量
            List<CommissionGoodsMq> goodsMqs = new ArrayList<>();
            for (RefundGoodsParam refundGoodsParam : refundOrderParam.getGoodsList()) {
                // 获取订单商品信息
                OrderDetail orderDetail = orderDetailMapper.selectOne(Wrappers.lambdaQuery(OrderDetail.class)
                        .eq(OrderDetail::getOrderId, order.getId())
                        .eq(OrderDetail::getGoodsId, refundGoodsParam.getGoodsId()));
                if (ObjectUtil.isNull(orderDetail) || orderDetail.getNumber() < refundGoodsParam.getNumber()) {
                    throw new BusinessException(500, "商品信息异常");
                }

                orderDetail.setNumber(orderDetail.getNumber() - refundGoodsParam.getNumber());
                orderDetailMapper.updateById(orderDetail);

                CommissionGoodsMq commissionGoodsMq = new CommissionGoodsMq();
                commissionGoodsMq.setGoodsId(refundGoodsParam.getGoodsId());
                commissionGoodsMq.setSellPrice(orderDetail.getSellPrice());
                commissionGoodsMq.setNumber(refundGoodsParam.getNumber());
                commissionGoodsMq.setCategoryId(orderDetail.getCategoryId());
                goodsMqs.add(commissionGoodsMq);
            }
            // 退款后需要重新计算订单分润
            // 此处用来处理代理商当天分润，不一定准确，最终分润以定时任务统计为准
            CommissionOrderMq agentCommissionMq = new CommissionOrderMq();
            agentCommissionMq.setType(2);
            agentCommissionMq.setPayway(order.getPayway());
            agentCommissionMq.setShopId(order.getShopId());
            agentCommissionMq.setAmount(refund.getAmount());
            agentCommissionMq.setOrderId(order.getId());
            agentCommissionMq.setPayTime(refund.getCreateTime());
            agentCommissionMq.setGoodsMqs(goodsMqs);

            SendResult sendResult = rocketMQTemplate.syncSend(RocketMqConstant.AGENT_COMMISSION_TOPIC, JSON.toJSONString(agentCommissionMq), 3000);
            log.info(RocketMqConstant.AGENT_COMMISSION_TOPIC + " 推送到队列结果：" + sendResult);

            //插入退款单信息
            refund.setStatus(1);
            refund.setWxRefundId(lklRefundResponse.getTradeNo());

//            refund.setWxRefundId(result.get("refund_id"));
            refundMapper.updateById(refund);
            return true;
        } else {
            refund.setStatus(2);
//            refund.setErrorDesc(result.get("err_code_des"));
            refundMapper.updateById(refund);
            throw new BusinessException(500, "退款失败");
        }
    }

    public void orderLklSeparateUpdate(Order order) throws Exception {
        orderMapper.updateById(order);
    }

    @Override
    public OrderVo getOrderInfo(String orderNo) {
        // 根据订单号获取订单信息
        Order order = orderMapper.selectOne(
                Wrappers.lambdaQuery(Order.class).eq(Order::getOrderNo, orderNo));
        if (order == null) {
            throw new BusinessException("订单信息异常");
        }
        OrderVo orderVo = new OrderVo();
        BeanUtils.copyProperties(order, orderVo);
        // 获取订单详情
        List<OrderDetailVo> orderDetailVos = orderDetailMapper.getOrderDetailVoByOrderId(order.getId());
        orderVo.setOrderDetailVos(orderDetailVos);

        return orderVo;
    }

    @Override
    public RefundInfoVo getRefundInfo(String refundNo) {
        // 获取退款信息
        Refund refund = refundMapper.selectOne(Wrappers.lambdaQuery(Refund.class)
                .eq(Refund::getRefundNo, refundNo));
        if (refund == null) {
            throw new BusinessException("退款信息异常");
        }
        // 获取对应的订单信息
        Order order = orderMapper.selectById(refund.getOrderId());
        if (order == null) {
            throw new BusinessException("订单信息异常");
        }
        RefundInfoVo refundInfoVo = new RefundInfoVo();
        BeanUtils.copyProperties(order, refundInfoVo);
        BeanUtils.copyProperties(refund, refundInfoVo);
        refundInfoVo.setRefundAmount(refund.getAmount());
        // 获取订单退款详情
        List<RefundDetailVo> refundDetailVos = refundDetailMapper.getRefundDetailVoByRefundId(refund.getId());
        refundInfoVo.setRefundDetailList(refundDetailVos);

        return refundInfoVo;
    }

    @Override
    public Integer queryStatus(String orderNo) throws Exception {
        // 通过redis防止重复提交
        if (redisUtil.hasKey(CommonConstant.ORDER_QUERY_CHECK + orderNo)) {
            throw new BusinessException(500, "查询频率过快，请稍后再操作");
        }
        redisUtil.set(CommonConstant.ORDER_QUERY_CHECK + orderNo, 1, 1);
        // 根据订单号获取订单信息
        Order order = orderMapper.selectOne(
                Wrappers.lambdaQuery(Order.class).eq(Order::getOrderNo, orderNo));
        if (order == null) {
            throw new BusinessException("订单信息异常");
        }
        if (order.getStatus() == 0) {
            // 先去支付渠道查询一下订单状态，确认未支付则关闭订单
            WxQueryRequestParam wxQueryRequestParam = new WxQueryRequestParam();
            wxQueryRequestParam.setOutTradeNo(order.getOrderNo());
            Map<String, String> resultMap = wxPayService.orderQuery(wxQueryRequestParam);
            log.info("微信查询结果：" + JSONObject.toJSONString(resultMap));
            if ("SUCCESS".equals(resultMap.get("return_code")) && "SUCCESS".equals(resultMap.get("result_code"))
                    && "SUCCESS".equals(resultMap.get("trade_state"))) {
                // 如果已支付修改订单状态为已支付
                order.setStatus(1);
                //支付时间
                DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
                Date payTime = df.parse(resultMap.get("time_end"));
                order.setPayTime(payTime);
                //微信订单号
                order.setWxTransactionId(resultMap.get("transaction_id"));
                orderMapper.updateById(order);

                // 此处用来处理代理商当天分润，不一定准确，最终分润以定时任务统计为准
                CommissionOrderMq agentCommissionMq = new CommissionOrderMq();
                agentCommissionMq.setShopId(order.getShopId());
                agentCommissionMq.setAmount(order.getAmount());
                agentCommissionMq.setOrderId(order.getId());
                agentCommissionMq.setPayTime(order.getPayTime());
                SendResult sendResult = rocketMQTemplate.syncSend(RocketMqConstant.AGENT_COMMISSION_TOPIC, JSON.toJSONString(agentCommissionMq), 3000);
                log.info(RocketMqConstant.AGENT_COMMISSION_TOPIC + " 推送到队列结果：" + sendResult);
            }
        }

        return order.getStatus();
    }

    @Override
    public String getOrderBindingUrl(String orderNo) {
        return "https//www.baidu.com/" + orderNo;
    }

}
